using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using OneAuthCenter.Application.Common.Helpers;
using OneAuthCenter.Application.DTOs.User;
using OneAuthCenter.Application.Services;

namespace OneAuthCenter.API.Controllers;

/// <summary>
/// 用户管理控制器
/// </summary>
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class UserController : ControllerBase
{
    private readonly IUserService _userService;
    private readonly ILogger<UserController> _logger;

    public UserController(IUserService userService, ILogger<UserController> logger)
    {
        _userService = userService;
        _logger = logger;
    }

    /// <summary>
    /// 获取当前用户信息
    /// </summary>
    [HttpGet("me")]
    [ProducesResponseType(typeof(UserDto), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetCurrentUser()
    {
        try
        {
            var userIdClaim = User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier);
            if (userIdClaim == null || !int.TryParse(userIdClaim.Value, out var userId))
            {
                return Unauthorized(new { message = "无效的用户身份" });
            }

            var user = await _userService.GetUserByIdAsync(userId);
            if (user == null)
            {
                return NotFound(new { message = "用户不存在" });
            }

            return Ok(user);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取当前用户信息时发生错误");
            return StatusCode(500, new { message = "获取用户信息失败" });
        }
    }

    /// <summary>
    /// OpenID Connect UserInfo 端点
    /// </summary>
    /// <remarks>
    /// 根据 Access Token 中的 scopes 返回相应的用户信息
    /// 
    /// 支持的 scopes：
    /// - openid: sub（用户唯一标识符，始终返回）
    /// - profile: name, given_name, family_name, preferred_username
    /// - email: email, email_verified
    /// - phone: phone_number, phone_number_verified
    /// - address: address（地址信息）
    /// 
    /// 示例请求：
    /// GET /api/user/userinfo
    /// Authorization: Bearer {access_token}
    /// 
    /// 如果 Token 包含 scope="openid profile email"，则返回：
    /// {
    ///   "sub": "123",
    ///   "name": "张三",
    ///   "preferred_username": "zhangsan",
    ///   "email": "zhangsan@example.com",
    ///   "email_verified": true
    /// }
    /// 
    /// 如果 Token 仅包含 scope="openid"，则只返回：
    /// {
    ///   "sub": "123"
    /// }
    /// </remarks>
    [HttpGet("userinfo")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> UserInfo()
    {
        try
        {
            // 1. 验证用户身份
            var userIdClaim = User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier);
            if (userIdClaim == null || !int.TryParse(userIdClaim.Value, out var userId))
            {
                _logger.LogWarning("UserInfo 请求失败：无效的用户身份");
                return Unauthorized(new { error = "invalid_token" });
            }

            // 2. 获取用户信息
            var userDto = await _userService.GetUserByIdAsync(userId);
            if (userDto == null)
            {
                _logger.LogWarning("UserInfo 请求失败：用户不存在，UserId: {UserId}", userId);
                return NotFound(new { error = "user_not_found" });
            }

            // 3. 将 UserDto 转换为 User 实体（用于 ClaimHelper）
            var user = new OneAuthCenter.Domain.Entities.User
            {
                Id = userDto.Id,
                Username = userDto.Username,
                Email = userDto.Email,
                FullName = userDto.FullName,
                PhoneNumber = userDto.PhoneNumber
            };

            // 4. 从 Token 中提取 scopes
            var scopes = ClaimHelper.GetScopes(User);
            
            // 记录调试信息
            _logger.LogDebug("UserInfo 请求，UserId: {UserId}, Scopes: {Scopes}", 
                userId, string.Join(", ", scopes));

            // 5. 根据 scopes 构建响应（只返回已授权的信息）
            var userInfo = ClaimHelper.BuildUserInfoByClaims(user, scopes);

            return Ok(userInfo);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取 UserInfo 时发生错误");
            return StatusCode(500, new { error = "server_error" });
        }
    }

    /// <summary>
    /// 获取所有用户（仅管理员）
    /// </summary>
    [HttpGet]
    [Authorize(Roles = "Admin")]
    [ProducesResponseType(typeof(IEnumerable<UserDto>), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetAll()
    {
        try
        {
            var users = await _userService.GetAllUsersAsync();
            return Ok(users);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取用户列表时发生错误");
            return StatusCode(500, new { message = "获取用户列表失败" });
        }
    }

    /// <summary>
    /// 根据 ID 获取用户
    /// </summary>
    [HttpGet("{id}")]
    [ProducesResponseType(typeof(UserDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> Get(int id)
    {
        try
        {
            var user = await _userService.GetUserByIdAsync(id);
            if (user == null)
            {
                return NotFound(new { message = $"用户 ID {id} 不存在" });
            }
            return Ok(user);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取用户时发生错误");
            return StatusCode(500, new { message = "获取用户失败" });
        }
    }

    /// <summary>
    /// 更新用户信息
    /// </summary>
    [HttpPut("{id}")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> Update(int id, [FromBody] UserDto userDto)
    {
        try
        {
            await _userService.UpdateUserAsync(id, userDto);
            return NoContent();
        }
        catch (KeyNotFoundException ex)
        {
            _logger.LogWarning(ex, "更新用户失败: {UserId}", id);
            return NotFound(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "更新用户时发生错误");
            return StatusCode(500, new { message = "更新用户失败" });
        }
    }

    /// <summary>
    /// 删除用户（仅管理员）
    /// </summary>
    [HttpDelete("{id}")]
    [Authorize(Roles = "Admin")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    public async Task<IActionResult> Delete(int id)
    {
        try
        {
            await _userService.DeleteUserAsync(id);
            return NoContent();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "删除用户时发生错误");
            return StatusCode(500, new { message = "删除用户失败" });
        }
    }

    /// <summary>
    /// 修改密码
    /// </summary>
    [HttpPost("change-password")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> ChangePassword([FromBody] ChangePasswordRequest request)
    {
        try
        {
            var userIdClaim = User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier);
            if (userIdClaim == null || !int.TryParse(userIdClaim.Value, out var userId))
            {
                return Unauthorized(new { message = "无效的用户身份" });
            }

            await _userService.ChangePasswordAsync(userId, request.OldPassword, request.NewPassword);
            return NoContent();
        }
        catch (UnauthorizedAccessException ex)
        {
            _logger.LogWarning(ex, "修改密码失败");
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "修改密码时发生错误");
            return StatusCode(500, new { message = "修改密码失败" });
        }
    }
}

